(function (window) {
    const FULFILLED = 'fulfilled'
    const REJECTED = 'rejected'
    const PENDING = 'pendding'
    // 手写Promise
    function Promise(excutor) {
        // 初始化数据
        this.state = PENDING
        this.data = undefined
        this.callbacks = []
        // 保存this
        const self = this

        // resolve函数
        function resolve(value) {
            if (self.state !== PENDING) return
            self.state = FULFILLED
            self.data = value
            if (self.callbacks.length > 0) {
                // 保证then中的回调函数异步执行(这里的微任务用宏任务代替)
                setTimeout(() => {
                    self.callbacks.forEach(callback => callback.resolved(value))
                })
            }
        }
        // reject函数
        function reject(reason) {
            if (self.state !== PENDING) return
            self.state = REJECTED
            self.data = reason
            if (self.callbacks.length > 0) {
                setTimeout(() => {
                    self.callbacks.forEach(callback => callback.rejected(reason))
                })
            }
        }

        // 错误处理
        try {
            // 调用执行器函数
            excutor(resolve, reject)
        } catch (error) {
            reject(error)
        }
    }


    // 定义实例方法(then,catch,finally)
    Promise.prototype.then = function (onResolved, onRejected) {
        // 暂存this
        const self = this
        // 如果传入的两个参数不是函数需要对其进行处理
        onResolved = typeof onResolved === 'function' ? onResolved : value => value
        onRejected = typeof onRejected === 'function' ? onRejected : reason => {
            throw reason
        }
        return new Promise((resolve, reject) => {

            // 声明处理Promise三种状态的函数
            function handle(callback) {
                // 回调函数可能有三种情况：Promise,非Promise,抛出错误
                try {
                    const result = callback(self.data)
                    if (result instanceof Promise) {
                        // 如果result的值是Promise实例那么就调用then方法改变当前promise的状态
                        result.then(value => resolve(value), reason => reject(reason))
                    } else {
                        // 如果result不是Promise的值那么说明其是非Promise值
                        resolve(result)
                    }
                } catch (error) {
                    // 如果捕获到错误就立即改变当前Promise的状态为失败状态
                    reject(error)
                }
            }
            // 在执行then之前要判断调用then方法的promise的状态(fulfilled,rejected,pendding)
            if (self.state === FULFILLED) {
                // 如果是成功状态就异步调用handle改变当前promise的状态
                setTimeout(() => {
                    handle(onResolved)
                })
            } else if (self.state === REJECTED) {
                // 如果是失败状态就异步调用handle改变当前promise的状态
                setTimeout(() => {
                    handle(onRejected)
                })
            } else {
                // 如果是等待状态就先把回调函数存到callbacks队列中，待状态修改为成功/失败时再异步执行
                self.callbacks.push({
                    resolved: () => handle(onResolved),
                    rejected: () => handle(onRejected)
                })
            }
        })
    }



    // catch的本质就是then方法，特点是只接收失败状态，对成功的值进行向下穿透的效果
    Promise.prototype.catch = function (onRejected) {
        return this.then(value => value, onRejected)
    }


    // 无论调用finally的Promise是成功状态还是失败状态，onFinal函数都会执行
    Promise.prototype.finally = function (onFinal) {
        const self = this
        return new Promise((resolve, reject) => {
            self.then(value => {
                resolve(value)
                onFinal()
            }, reason => {
                reject(reason)
                onFinal()
            })
        })
    }



    // Promise的静态方法，实例无法访问(resolve,reject,all,allSettled,race)
    Promise.resolve = function (value) {
        return new Promise((resolve, reject) => {
            // 如果value是Promise实例
            if (value instanceof Promise) {
                value.then(value => resolve(value), reason => reject(reason))
            } else {
                resolve(value)
            }
        })
    }

    Promise.reject = function (reason) {
        return new Promise((resolve, reject) => {
            reject(reason)
        })
    }

    // 接收多个promise组成的数组，返回所有value和reason的结果组成的数组,只有当所有的promise都成功才成功
    Promise.all = function (promises) {
        const results = []
        let promiseCount = 0
        return new Promise((resolve, reject) => {
            promises.forEach((promise, index) => {
                promise.then(value => {
                    results[index] = value
                    promiseCount++
                    if (promiseCount === promises.length) resolve(results)
                }, reason => reject(reason))
            })
        })
    }


    Promise.allSettled = function (promises) {
        const results = []
        let settledCount = 0
        return new Promise((resolve, reject) => {
            promises.forEach((promise, index) => {
                promise.then(value => {
                    results[index] = {
                        status: 'fulfilled',
                        value
                    }
                    settledCount++
                    if (settledCount === promises.length) resolve(results)
                }, reason => {
                    results[index] = {
                        status: 'rejected',
                        reason
                    }
                    settledCount++
                    if (settledCount === promises.length) resolve(results)
                })
            })
        })
    }


    Promise.race = function (promises) {
        return new Promise((resolve, reject) => {
            promises.forEach(promise => {
                promise.then(value => resolve(value), reason => reject(reason))
            })
        })
    }
    window.Promise = Promise
})(window)